/** 扫码盒子 / 扫码抢对接 工具 */

// 设备是否触发回车
let isEnter = true;

// 缓存输入的字符串
let inputCache = "";

/**
 * 初始化监听
 * @param callback 回调函数
 * @param haveEnter 是否有结束通知事件 （默认true）
 */
export const initScanBox = (callback: (result: any) => void = (result) => {}, haveEnter: boolean = true) => {
  isEnter = haveEnter;
  // 监听键盘事件
  // #ifdef APP-PLUS
  plus.key.addEventListener("keyup", isEnter ? keypress : keypressByNotKey);
  // #endif
  // #ifdef H5
  document.addEventListener("keyup", isEnter ? keypress : keypressByNotKey);
  // #endif
  // 监听扫码结果
  uni.$on("scan-code:enter", callback);
};

// 销毁监听
export const destroyScanBox = () => {
  // 销毁监听键盘事件
  // #ifdef APP-PLUS
  plus.key.removeEventListener("keyup", isEnter ? keypress : keypressByNotKey);
  // #endif
  // #ifdef H5
  document.removeEventListener("keyup", isEnter ? keypress : keypressByNotKey);
  // #endif
  // 销毁监听扫码结果
  uni.$off("scan-code:enter");
  // 清空缓存
  inputCache = "";
};

// 键盘事件
const keypress = (e: any) => {
  if (e.keyCode === 66 || e.key == "Enter") {
    // 全局事件通知
    uni.$emit("scan-code:enter", inputCache);
    inputCache = "";
  } else {
    // #ifdef APP-PLUS
    inputCache += codeToStr(e.keyCode) || "";
    // #endif
    // #ifdef H5
    inputCache += e.key;
    // #endif
  }
};

// 无触发回车的情况
let timer: any;
// 处理阈值
const delay = 500;

const keypressByNotKey = (e: any) => {

  // 因为有些设备并不通知回车，所以利用防抖的方式来处理

  if (timer) clearTimeout(timer);
  timer = null;
  timer = setTimeout(() => {
    // 模拟回车通知接收
    // 全局事件通知
    uni.$emit("scan-code:enter", inputCache);
    inputCache = "";
  }, delay);

  // 正常的键盘事件
  // #ifdef APP-PLUS
  inputCache += codeToStr(e.keyCode) || "";
  // #endif
  // #ifdef H5
  inputCache += e.key;
  // #endif
};

// keymap.js 以下来源网络收集，不同的设备对应的keyCode可能不同,目前为安卓平台测试结果
// 大概率是ASCII偏移了
const keyMap = {
  7: "0",
  8: "1",
  9: "2",
  10: "3",
  11: "4",
  12: "5",
  13: "6",
  14: "7",
  15: "8",
  16: "9",
  29: "A",
  30: "B",
  31: "C",
  32: "D",
  33: "E",
  34: "F",
  35: "G",
  36: "H",
  37: "I",
  38: "J",
  39: "K",
  40: "L",
  41: "M",
  42: "N",
  43: "O",
  44: "P",
  45: "Q",
  46: "R",
  47: "S",
  48: "T",
  49: "U",
  50: "V",
  51: "W",
  52: "X",
  53: "Y",
  54: "Z",
  55: ",",
  56: ".",
  59: "",
  69: "-",
  70: "=",
  81: "+",
  74: ":",
};

function codeToStr(code: keyof typeof keyMap): String {
  return keyMap[code];
}
